// excerpts from http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#ifndef MUDUO_NET_TCPSERVER_H
#define MUDUO_NET_TCPSERVER_H

#include "Callbacks.h"
#include "TcpConnection.h"

#include <map>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <string>

namespace learnmuduo
{

class Acceptor;
class EventLoop;

class TcpServer : boost::noncopyable
{
 public:
   TcpServer(EventLoop *loop, const InetAddress &listenAddr);
   TcpServer(EventLoop* loop, const InetAddress& listenAddr, std::string name);
  ~TcpServer();  // force out-line dtor, for scoped_ptr members.

  /// Starts the server if it's not listenning.
  ///
  /// It's harmless to call it multiple times. 可重复调用；内部通过状态位保证幂等
  /// Thread safe.
  void start();

  /// Set connection callback. 设置用户层的连接回调（连接建立/断开时触发）
  /// Not thread safe.
  void setConnectionCallback(const ConnectionCallback& cb)
  { connectionCallback_ = cb; }

  /// Set message callback. 设置用户层的消息回调（有数据到达时触发）
  /// Not thread safe.
  void setMessageCallback(const MessageCallback& cb)
  { messageCallback_ = cb; }

 private:
  /// Not thread safe, but in loop. acceptor 接收到新连接时回调此函数
  void newConnection(int sockfd, const InetAddress& peerAddr);

  typedef std::map<std::string, TcpConnectionPtr> ConnectionMap;

  EventLoop* loop_;  // the acceptor loop; 持有 Acceptor 的主循环（通常即 IO 线程）。
  const std::string name_; // 服务器名称（用于日志、连接命名等）
  boost::scoped_ptr<Acceptor> acceptor_; // avoid revealing Acceptor
  ConnectionCallback connectionCallback_; // 用户设置的连接回调
  MessageCallback messageCallback_; // 用户设置的消息回调
  bool started_; // 是否已调用过 start()
  int nextConnId_;  // always in loop thread; 用于给新连接生成唯一 ID，始终在 loop 线程中递增
  ConnectionMap connections_; // TcpServer持有目前存活的TcpConnection的shared_ptr（定义为TcpConnectionPtr）​，因为TcpConnection对象的生命期是模糊的，用户也可以持有TcpConnectionPtr。
};

}

#endif  // MUDUO_NET_TCPSERVER_H
